package com.hrm.attendance;

import com.hrm.common.shiro.realm.HrmRealm;
import com.hrm.common.shiro.session.CustomSessionManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shrio的配置类
 */
@Configuration
public class ShiroConfiguration {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private String port;

    /**
     * 配置自定义realm
     */
    @Bean
    public HrmRealm getRealm() {
        return new HrmRealm();
    }

    /**
     * shiro redisManager
     */
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(host + ":" + port);
        return redisManager;
    }

    /**
     * shiro redis SessionDao层的实现
     */
    public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        return redisSessionDAO;
    }

    /**
     * cacheManager实现 redis实现
     */
    public RedisCacheManager redisCacheManager() {
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
    }

    /**
     * shiro session管理,自定义session管理
     */
    public DefaultSessionManager defaultSessionManager(){
        CustomSessionManager customSessionManager = new CustomSessionManager();
        customSessionManager.setSessionDAO(redisSessionDAO());
        //禁用使用cookide
        customSessionManager.setSessionIdCookieEnabled(false);
        //禁用重写url
        customSessionManager.setSessionIdUrlRewritingEnabled(false);
        return customSessionManager;
    }

    /**
     * 配置安全管理器
     */
    @Bean
    public SecurityManager securityManager() {
        //1、使用默认web安全管理器
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //2、自定义session管理
        securityManager.setSessionManager(defaultSessionManager());
        //3、自定义缓存实现：redis
        securityManager.setCacheManager(redisCacheManager());
        //4、注册自定义realm
        securityManager.setRealm(getRealm());
        return securityManager;
    }

    /**
     * 配置shiro过滤器
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        //1、创建工厂对象
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //2、设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //3、配置登录页面、验证未通过页面
        shiroFilterFactoryBean.setLoginUrl("/autherror?code=1");
        shiroFilterFactoryBean.setUnauthorizedUrl("/autherror?code=2");
        //4、配置过滤器map集合,顺序拦截
        Map<String, String> map = new LinkedHashMap<>();
        map.put("/sys/login", "anon"); //匿名可使用
        map.put("/sys/faceLogin/**","anon");
        map.put("/autherror", "anon"); //匿名可使用
        map.put("/**", "authc"); //需要认证
        /*具有权限perm使用@require注解*/

        //5、设置过滤器
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    /**
     * 配置shiro注解支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }


}
